package com.iocup.keybastion.authentication.impl;


import com.iocup.keybastion.authentication.AccessToken;
import com.iocup.keybastion.authentication.RefreshToken;
import lombok.Getter;

import java.beans.Transient;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 默认token实现
 *
 * @author xyjxust
 * @create 2021/11/24 15:26
 **/
public class DefaultAccessToken implements AccessToken {
    /**
     * 生成的token
     */
    @Getter
    private String accessToken;
    /**
     * 进行刷新的token
     */
    private RefreshToken refreshTokenObj;
    /**
     * 过期时间
     */
    @Getter
    private Date expireTime;
    /**
     * token类型
     */
    @Getter
    private String tokenType;
    /**
     * 其他携带信息
     */
    private Map<String, Object> other = new HashMap<>();


    public DefaultAccessToken() {

    }

    private DefaultAccessToken(String accessToken) {
        this.tokenType = "Bearer".toLowerCase();
        this.accessToken = accessToken;
    }

    public static DefaultAccessToken build(String accessToken) {
        return new DefaultAccessToken(accessToken);
    }

    public DefaultAccessToken expireTime(Date expireTime) {
        this.expireTime = expireTime;
        return this;
    }

    public DefaultAccessToken refreshToken(RefreshToken refreshToken) {
        this.refreshTokenObj = refreshToken;
        return this;
    }

    public DefaultAccessToken otherValue(String key, String value) {
        other.put(key, value);
        return this;
    }


    @Override
    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    @Transient
    public RefreshToken getRefreshTokenObj() {
        return refreshTokenObj;
    }

    public void setRefreshTokenObj(RefreshToken refreshTokenObj) {
        this.refreshTokenObj = refreshTokenObj;
    }

    public void setExpireTime(Date expireTime) {
        this.expireTime = expireTime;
    }

    @Override
    public String getTokenType() {
        return tokenType;
    }

    public void setTokenType(String tokenType) {
        this.tokenType = tokenType;
    }

    public void setOther(Map<String, Object> other) {
        this.other = other;
    }

    @Override
    public String getRefreshToken() {
        return refreshTokenObj == null ? "" : refreshTokenObj.getToken();
    }

    public void setRefreshToken(String token) {

    }

    @Transient
    @Override
    public RefreshToken getRToken() {
        return this.refreshTokenObj;
    }

    @Transient
    @Override
    public Date getExpireTime() {
        return this.expireTime;
    }

    @Transient
    @Override
    public boolean isExpire() {
        return getExpireTime().before(new Date());
    }

    @Override
    public Integer getExpiresIn() {
        return this.expireTime != null ? Long.valueOf((this.expireTime.getTime() - System.currentTimeMillis()) / 1000L).intValue() : 0;
    }

    public void setExpiresIn(Integer expiresIn) {
        this.expireTime = new Date(System.currentTimeMillis() + expiresIn * 1000L);
    }


    @Override
    public <T> T getOther(String key) {
        return other.containsKey(key) ? (T) other.get(key) : null;
    }

    @Transient
    public Map<String, Object> getOther() {
        return other;
    }
}
